import { GetChangedBackgroundResultMessage, PostMessageType } from '@/config';
import { delay, generateRandomId, waitEleRender } from '@/lib/utils';

let iframeWindow: Window | null = null;
// 生成一个 map 来存储任务
const taskMap = new Map<
  string,
  {
    resolve: (value: { resultUrl: string; resultBlob: Blob }) => void;
    reject: (reason?: any) => void;
  }
>();
export async function getIframeWindow() {
  if (iframeWindow) {
    return iframeWindow;
  } else {
    const iframeEle = (await waitEleRender(
      `#dianxiaomi-meituxiuxiu-iframe`,
      5000,
    )) as HTMLIFrameElement | null;
    iframeWindow = iframeEle && iframeEle.contentWindow;
    return iframeWindow;
  }
}

async function handleMessage(message: MessageEvent<GetChangedBackgroundResultMessage>) {
  if (message.origin.includes(chrome.runtime.id)) {
    if (message.data.type === PostMessageType.getChangedBackgroundResult) {
      const { taskId, errorCode, errorMessage, resultUrl, resultBlob } = message.data.data;
      const task = taskMap.get(taskId);
      if (task) {
        const { resolve, reject } = task;
        if (errorCode === 0) {
          resolve({
            resultUrl,
            resultBlob,
          });
        } else {
          reject(new Error(`执行替换背景失败: ${errorMessage}`));
        }
      }
    }
  }
}
window.addEventListener('message', handleMessage);

export function useMeituxiuxiu() {
  const generateAIImage = useCallback(
    async (
      sourceImage: Blob,
    ): Promise<{
      resultUrl: string;
      resultBlob: Blob;
    }> => {
      return new Promise(async (resolve, reject) => {
        const iframeWindow = await getIframeWindow();
        if (iframeWindow) {
          const taskId = generateRandomId();
          taskMap.set(taskId, {
            resolve,
            reject,
          });
          iframeWindow.postMessage(
            {
              type: PostMessageType.changeBackground,
              data: {
                sourceImage,
                taskId,
              },
            },
            browser.runtime.getURL('/dianxiaomi-meituxiuxiu-html.html'),
          );
        } else {
          reject(new Error('找不到 iframeWindow,无法发起请求'));
        }
      });
    },
    [],
  );

  const generateAIImageLoop = useCallback(
    async (
      sourceImage: Blob,
      aiRetryTime: number,
      retryCallback: (error: unknown) => void,
    ): Promise<{
      resultUrl: string;
      resultBlob: Blob;
    }> => {
      try {
        return await generateAIImage(sourceImage);
      } catch (error) {
        console.log(error);
        if (aiRetryTime > 0) {
          retryCallback(error);
          // 随机延迟 2 到 6 秒
          await delay(Math.floor(Math.random() * 4000) + 2000);
          return generateAIImageLoop(sourceImage, aiRetryTime - 1, retryCallback);
        } else {
          throw error;
        }
      }
    },
    [generateAIImage],
  );

  return {
    generateAIImage,
    generateAIImageLoop,
  };
}
